package product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.feign.constant.ProductConstant;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import product.constant.AttrConstant;
import product.domain.*;
import product.mapper.AttrAttrgroupRelationMapper;
import product.mapper.AttrGroupMapper;
import product.mapper.CategoryMapper;
import product.service.AttrService;
import product.mapper.AttrMapper;
import org.springframework.stereotype.Service;
import product.utils.GetUtils;
import product.vo.AttrRespVo;
import product.vo.AttrVo;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author panghu
 * @description 针对表【pms_attr(商品属性)】的数据库操作Service实现
 * @createDate 2023-03-04 21:03:08
 */
@Service
public class AttrServiceImpl extends CommonServiceImpl<AttrMapper, Attr>
        implements AttrService {

    @Autowired
    private AttrAttrgroupRelationMapper attrAttrgroupRelationMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private AttrGroupMapper attrGroupMapper;

    @Autowired
    private GetUtils getUtils;

    @Override
    public Page<AttrRespVo> queryPageWithAttrRespVo(Map<String, Object> params, Long catId) {
        LambdaQueryWrapper<Attr> queryWrapper;
        if (catId == 0) {
            // 查询所有
            queryWrapper = getQueryWrapper(params);
        } else {
            queryWrapper = getQueryWrapper(params).eq(Attr::getCatelogId, catId);
        }
        // 大数量下不推荐联表查询，会出现很大的笛卡尔积。应分别查询。
        Page<Attr> attrPage = this.baseMapper.selectPage(new Page<>(Integer.parseInt((String) params.get("page")), Integer.parseInt((String) params.get("limit"))), queryWrapper);
        List<Attr> attrList = attrPage.getRecords();
        List<AttrRespVo> attrRespVoList = attrList.stream().map(attr -> {
            AttrRespVo attrRespVo = new AttrRespVo();
            BeanUtils.copyProperties(attr, attrRespVo);
            // 查询属性属性分组关系
            if (params.get("attrType").toString().equalsIgnoreCase("base")) {
                AttrAttrgroupRelation attrAttrgroupRelation = attrAttrgroupRelationMapper.selectOne(new LambdaQueryWrapper<AttrAttrgroupRelation>().eq(AttrAttrgroupRelation::getAttrId, attr.getAttrId()));
                // todo this.groupid不能为null吗
                if (!ObjectUtils.isEmpty(attrAttrgroupRelation) && attrAttrgroupRelation.getAttrGroupId() != null) {
                    // 查询分组
                    AttrGroup attrGroup = attrGroupMapper.selectById(attrAttrgroupRelation.getAttrGroupId());
                    if (!ObjectUtils.isEmpty(attrGroup)) {
                        // 设置分组名称
                        attrRespVo.setGroupName(attrGroup.getAttrGroupName());
                    }
                }
            }
            // 查询分类
            Category category = categoryMapper.selectById(attr.getCatelogId());
            if (!ObjectUtils.isEmpty(category)) {
                // 设置分类名称
                attrRespVo.setCatelogName(category.getName());
            }
            return attrRespVo;
        }).collect(Collectors.toList());
        Page<AttrRespVo> attrRespVoPage = new Page<>(Integer.parseInt((String) params.get("page")), Integer.parseInt((String) params.get("limit")));
        attrRespVoPage.setRecords(attrRespVoList);
        return attrRespVoPage;
    }

    @Override
    @Transactional
    public boolean saveAttr(AttrVo attrVo) {
        Attr attr = new Attr();
        // 保存属性
        BeanUtils.copyProperties(attrVo, attr);
        boolean saveResult = this.save(attr);
        // 如果是基本属性才需要保存关联关系
        if (attrVo.getAttrType().equals(ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) && attrVo.getAttrGroupId() != null) {
            // 保存属性、属性分组关联表
            AttrAttrgroupRelation attrAttrgroupRelation = new AttrAttrgroupRelation();
            attrAttrgroupRelation.setAttrGroupId(attrVo.getAttrGroupId());
            attrAttrgroupRelation.setAttrId(attr.getAttrId());
            attrAttrgroupRelationMapper.insert(attrAttrgroupRelation);
        }
        return saveResult;
    }

    @Override
    public AttrRespVo getAttrVoById(Long attrId) {
        Attr attr = baseMapper.selectById(attrId);
        AttrRespVo attrRespVo = new AttrRespVo();
        BeanUtils.copyProperties(attr, attrRespVo);
        // 如果是基本属性才需要更新分组信息
        if (attr.getAttrType().equals(ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())) {
            // 根据属性id查询属性与属性分组关系
            AttrAttrgroupRelation attrAttrgroupRelation = attrAttrgroupRelationMapper.selectOne(new LambdaQueryWrapper<AttrAttrgroupRelation>().eq(AttrAttrgroupRelation::getAttrId, attrId));
            // 设置分组信息
            if (!ObjectUtils.isEmpty(attrAttrgroupRelation)) {
                // 查询属性分组
                AttrGroup attrGroup = attrGroupMapper.selectById(attrAttrgroupRelation.getAttrGroupId());
                if (!ObjectUtils.isEmpty(attrGroup)) {
                    attrRespVo.setAttrGroupId(attrGroup.getAttrGroupId());
                    attrRespVo.setGroupName(attrGroup.getAttrGroupName());
                }
            }
        }
        // 设置分类信息
        Category category = categoryMapper.selectById(attr.getCatelogId());
        if (!ObjectUtils.isEmpty(category)) {
            // 设置分类名称
            attrRespVo.setCatelogName(category.getName());
            List<Long> paths = new ArrayList<>();
            List<Long> catelogPath = getUtils.getCategoryIdPath(category.getCatId(), paths);
            Collections.reverse(catelogPath);
            // 设置分类路径
            attrRespVo.setCatelogPath(catelogPath.toArray(new Long[0]));
        }
        return attrRespVo;
    }

    @Override
    @Transactional
    public boolean updateWithRelationById(AttrVo attrVo) {
        Attr attr = new Attr();
        BeanUtils.copyProperties(attrVo, attr);
        baseMapper.updateById(attr);
        // 如果是基本属性才需要更新分组关联信息
        if (attr.getAttrType().equals(ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())) {
            // 更新分类路径
            AttrAttrgroupRelation attrAttrgroupRelation = new AttrAttrgroupRelation();
            attrAttrgroupRelation.setAttrGroupId(attrVo.getAttrGroupId());
            attrAttrgroupRelation.setAttrId(attrVo.getAttrId());
            Long count = attrAttrgroupRelationMapper.selectCount(new LambdaQueryWrapper<AttrAttrgroupRelation>().eq(AttrAttrgroupRelation::getAttrId, attrVo.getAttrId()));
            if (count > 0) {
                // 更新操作
                int result = attrAttrgroupRelationMapper.update(attrAttrgroupRelation, new QueryWrapper<AttrAttrgroupRelation>().eq("attr_id", attrVo.getAttrId()));
            } else {
                // 新增操作
                attrAttrgroupRelationMapper.insert(attrAttrgroupRelation);
            }
        }
        return true;
    }

    @Override
    @Transactional
    public boolean removeBatchAttrByIds(List<Long> ids) {
        List<Attr> attrList = this.baseMapper.selectBatchIds(ids);
        for (Attr attr : attrList) {
            // 如果删除的是基本属性还需要删除对应的属性、属性分组关联表
            if (attr.getAttrType().equals(ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())) {
                attrAttrgroupRelationMapper.delete(new LambdaQueryWrapper<AttrAttrgroupRelation>().eq(AttrAttrgroupRelation::getAttrId, attr.getAttrId()));
            }
        }
        this.removeBatchByIds(ids);
        return true;
    }

    @Override
    public Page<Attr> getNoRelationAttr(Map<String, Object> params, Long attrGroupId) {
        // 1、当前分组只能关联自己所属的分类里面的所有属性
        AttrGroup attrGroup = attrGroupMapper.selectById(attrGroupId);
        Long catelogId = attrGroup.getCatelogId();
        // 2、当前分组只能关联别的分组没有引用的属性
        // 2.1、当前分类下的其他分组
        List<AttrGroup> attrGroupList = attrGroupMapper.selectList(new LambdaQueryWrapper<AttrGroup>().eq(AttrGroup::getCatelogId, catelogId));
        List<Long> attrGroupIds = attrGroupList.stream().map(AttrGroup::getAttrGroupId).collect(Collectors.toList());
        if (ObjectUtils.isEmpty(attrGroupIds)) {
            return null;
        }
        // 2.2、这些分组关联的属性
        List<AttrAttrgroupRelation> relationList = attrAttrgroupRelationMapper.selectList(new LambdaQueryWrapper<AttrAttrgroupRelation>().in(AttrAttrgroupRelation::getAttrGroupId, attrGroupIds));
        List<Long> attrIds = relationList.stream().map(AttrAttrgroupRelation::getAttrId).collect(Collectors.toList());
        // 2.3、从当前分类的所有属性中移除这些属性
        LambdaQueryWrapper<Attr> queryWrapper = getQueryWrapper(params);
        queryWrapper.eq(Attr::getCatelogId, catelogId).ne(Attr::getAttrType, ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());
        if (!ObjectUtils.isEmpty(attrIds)) {
            queryWrapper.notIn(Attr::getAttrId, attrIds);
        }
        Page<Attr> attrPage = new Page<>(Integer.parseInt((String) params.get("page")), Integer.parseInt((String) params.get("limit")));
        return this.baseMapper.selectPage(attrPage, queryWrapper);
    }


    @Override
    public Page<Attr> queryPage(Map<String, Object> params) {
        return null;
    }

    @Override
    public LambdaQueryWrapper<Attr> getQueryWrapper(Map<String, Object> params) {
        LambdaQueryWrapper<Attr> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(params.containsKey("key"), Attr::getAttrId, params.get("key")).or().like(params.containsKey("key"), Attr::getAttrName, params.get("key"));
        if (params.containsKey("attrType")) {
            queryWrapper.eq(params.get("attrType").equals("sale"), Attr::getAttrType, AttrConstant.ATTR_TYPE_SALE);
            queryWrapper.eq(params.get("attrType").equals("base"), Attr::getAttrType, AttrConstant.ATTR_TYPE_BASE);
            queryWrapper.eq(params.get("attrType").equals("all"), Attr::getAttrType, AttrConstant.ATTR_TYPE_ALL);
        }
        return queryWrapper;
    }

    /**
     * 根据分组id找到关联的所有属性
     *
     * @param attrgroupId
     * @return
     */
    @Override
    public List<Attr> getRelationAttr(Long attrgroupId) {

        List<AttrAttrgroupRelation> entities = attrAttrgroupRelationMapper.selectList
                (new QueryWrapper<AttrAttrgroupRelation>().eq("attr_group_id", attrgroupId));

        List<Long> attrIds = entities.stream().map(AttrAttrgroupRelation::getAttrId).collect(Collectors.toList());

        //根据attrIds查找所有的属性信息
        //Collection<AttrEntity> attrEntities = this.listByIds(attrIds);

        //如果attrIds为空就直接返回一个null值出去
        if (attrIds.size() == 0) {
            return null;
        }

        return this.baseMapper.selectBatchIds(attrIds);
    }

    @Override
    public List<Attr> getListByCatId(Long catId) {
        // 如果catId=0L，查询全部
        if (catId == 0L) {
            return this.baseMapper.selectList(null);
        }
        return this.baseMapper.selectList(new LambdaQueryWrapper<Attr>().eq(Attr::getCatelogId, catId));
    }


}




